﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using EmptyWallGallery.Core.BLL;
using Microsoft.VisualBasic;

namespace EmptyWallGallery.Core.Utilities
{
    public class Common
    {
        public static Common Instance
        {
            get { return new Common(); }
        }

        public bool IsMobile()
        {
            var useragent = HttpContext.Current.Request.UserAgent;
            //Response.Write(useragent);
            //Response.End();

            return (useragent != null && useragent.IndexOf("iPhone", StringComparison.Ordinal) > 1) ||
                   (useragent.IndexOf("Android", StringComparison.Ordinal) > 1);
        }

        public void SendEmailPassword(string title, string userName, string email, string password)
        {
            using (var sReader = new StreamReader(Configs.FolderSaveData.Replace("Resource", "template") + "LostPassword_Admin.htm", Encoding.UTF8))
            {
                var strContent = sReader.ReadToEnd();
                strContent = strContent.Replace("{WebTitle}", Configs.WebTitle);
                strContent = strContent.Replace("{0}", userName);
                strContent = strContent.Replace("{1}", password);
                strContent = strContent.Replace("{2}", Configs.HomeUrlAdmin + "Account/ChangePassword.aspx");

                //Send Mail Password
                SendMail(email, title, strContent, "");
            }
        }

        public void SendMail(string iTo, string subject, string body, string cc)
        {
            var mailer = new Mail(Configs.SmtpHost, Configs.SmtpUser, Configs.SmtpPass,
                                  Configs.WebMasterEmail);
            mailer.Send(iTo, subject, body, true, cc);
        }

        /// <summary>
        /// Get File Extension
        /// </summary>
        /// <param name="fileName">String file name</param>
        /// <returns>String Extension</returns>
        public string FileExtension(string fileName)
        {
            return !string.IsNullOrEmpty(fileName) ? new FileInfo(fileName).Extension.ToLower() : null;
        }

        public bool IsGUID(string expression)
        {
            if (expression != null)
            {
                var guidRegEx = new Regex(@"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");

                return guidRegEx.IsMatch(expression);
            }
            return false;
        }

        /// <summary>
        /// Check File Is Valid
        /// </summary>
        /// <param name="postedFile">File Upload</param>
        /// <param name="fileExt">Array File Extension</param>
        /// <returns>True|False</returns>
        public bool IsValidFile(HttpPostedFile postedFile, string[] fileExt)
        {
            var fileEx = Right(postedFile.FileName, 3);
            return fileExt.Any(fileEx.Contains);
        }

        public string WriteSubMenu(int catId, int subCatId, int subCatxId)
        {
            var strOut = new StringBuilder();
            strOut.Append("<ul>");
            switch (catId)
            {
                case 0:
                    strOut.Append("     <li class=\"home\"><span>Trang chủ</span></li>");
                    break;
                case 1:
                    strOut.Append("     <li class=\"home\"><a href=\"").Append(Configs.HomeUrl).Append("\" title=\"Trang chủ\"><span>Trang chủ</span></a></li>");
                    strOut.Append("     <li><span>Giới thiệu</span></li>");
                    break;
                case 9996:
                    strOut.Append("     <li class=\"home\"><a href=\"").Append(Configs.HomeUrl).Append("\" title=\"Trang chủ\"><span>Trang chủ</span></a></li>");
                    strOut.Append("     <li><span>Thông tin liên hệ</span></li>");
                    break;
                case 9997:
                    strOut.Append("     <li class=\"home\"><a href=\"").Append(Configs.HomeUrl).Append("\" title=\"Trang chủ\"><span>Trang chủ</span></a></li>");
                    strOut.Append("     <li><span>Thủ tục giao dịch</span></li>");
                    break;
                case 9998:
                    strOut.Append("     <li class=\"home\"><a href=\"").Append(Configs.HomeUrl).Append("\" title=\"Trang chủ\"><span>Trang chủ</span></a></li>");
                    strOut.Append("     <li><span>Giao dịch trực tuyến</span></li>");
                    break;
                case 9999:
                    strOut.Append("     <li class=\"home\"><a href=\"").Append(Configs.HomeUrl).Append("\" title=\"Trang chủ\"><span>Trang chủ</span></a></li>");
                    strOut.Append("     <li><span>Liên hệ</span></li>");
                    break;
                default:
                    strOut.Append("     <li class=\"home\"><a href=\"").Append(Configs.HomeUrl).Append("\" title=\"Trang chủ\"><span>Trang chủ</span></a></li>");
                    
                    var category = Categories.Instance.GetById(catId);
                    if (subCatId == 0)
                    {
                        strOut.Append("<li><span>").Append(category.Title).Append("</span></li>");
                    }
                    else
                    {
                        strOut.Append("<li><a href=\"/c").Append(category.CatId).Append("s").Append(
                            category.SubCat).Append("x").Append(category.SubCatx).Append(
                                "/").Append(category.TitleNone).Append("\" title=\"").Append(
                                    category.Title).Append("\"><span>").Append(
                                        category.Title).Append("</span></a></li>");

                        var category2 = Categories.Instance.GetById(subCatId);
                        strOut.Append("<li><span>").Append(category2.Title).Append("</span></li>");
                    }
                    break;
            }

            strOut.Append("</ul>");
            return strOut.ToString();
        }

        /// <summary>
        /// Delete file from Server
        /// </summary>
        /// <param name="strPath">Full path to file</param>
        /// <returns>True|False</returns>
        public bool DeleteFile(string strPath)
        {
            try
            {
                var theFile = new FileInfo(strPath);
                if (theFile.Exists)
                {
                    File.Delete(strPath);
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// Return Hexa Value
        /// </summary>
        /// <param name="i">Integer input</param>
        /// <returns>String hexa value</returns>
        public string HexValue(int i)
        {
            return i.ToString("X");
        }

        /// <summary>
        /// Return Integer Value
        /// </summary>
        /// <param name="hexValue">String Hexa input</param>
        /// <returns>Integer value from hexa string</returns>
        public int IntValue(string hexValue)
        {
            return int.Parse(hexValue, NumberStyles.HexNumber);
        }

        /// <summary>
        /// Check string is numeric
        /// </summary>
        /// <param name="value">String to check</param>
        /// <returns>True|False</returns>
        public bool IsNumeric(string value)
        {
            double num;
            return double.TryParse(value.Trim(), out num);
        }

        /// <summary>
        /// Set Session Value
        /// </summary>
        /// <param name="sessionName">Name of session</param>
        /// <param name="sessionValue">Value of session</param>
        public void SetSession(string sessionName, string sessionValue)
        {
            HttpContext.Current.Session.Add(sessionName, sessionValue);
        }

        /// <summary>
        /// Return Session Value
        /// </summary>
        /// <param name="sessionName">Name of session</param>
        /// <returns>Value of session</returns>
        public string GetSession(string sessionName)
        {
            string sessionval;
            try
            {
                sessionval = HttpContext.Current.Session[sessionName].ToString();
            }
            catch (Exception)
            {
                sessionval = "";

            }
            return sessionval;
        }

        /// <summary>
        /// Set Cookie Value
        /// </summary>
        /// <param name="cookieName">Name of cookie</param>
        /// <param name="cookieValue">Cookie value</param>
        /// <param name="expiresDate">Cookie expire date</param>
        /// <param name="domain">Cookie domain</param>
        public void SetCookie(string cookieName, string cookieValue, DateTime expiresDate, string domain = "")
        {
            var httpCookie = HttpContext.Current.Response.Cookies[cookieName];
            if (httpCookie != null) {
                httpCookie.Value = cookieValue;
                httpCookie.Expires = expiresDate;
            }
            if (domain == null) return;
            if (httpCookie != null)
                httpCookie.Domain = domain;
        }

        /// <summary>
        /// Get Cookie Value
        /// </summary>
        /// <param name="cookieName">Name of cookie</param>
        /// <returns>Cookie value</returns>
        public string GetCookie(string cookieName)
        {
            string cookieval = null;
            try
            {
                var httpCookie = HttpContext.Current.Request.Cookies[cookieName];
                if (httpCookie != null)
                    cookieval = httpCookie.Value;
            }
            catch (Exception)
            {
                cookieval = "";
            }
            return cookieval;
        }

        public string Truncate(string s, int length, bool atWord, bool addEllipsis)
        {
            // Return if the string is less than or equal to the truncation length
            if (s == null || s.Length <= length)
                return s;

            // Do a simple tuncation at the desired length
            var s2 = s.Substring(0, length);

            // Truncate the string at the word
            if (atWord)
            {
                // List of characters that denote the start or a new word (add to or remove more as necessary)
                var alternativeCutOffs = new List<char> { ' ', ',', '.', '?', '/', ':', ';', '\'', '\"', '\'', '-' };

                // Get the index of the last space in the truncated string
                var lastSpace = s2.LastIndexOf(' ');

                // If the last space index isn't -1 and also the next character in the original
                // string isn't contained in the alternativeCutOffs List (which means the previous
                // truncation actually truncated at the end of a word),then shorten string to the last space
                if (lastSpace != -1 && (s.Length >= length + 1 && !alternativeCutOffs.Contains(s.ToCharArray()[length])))
                    s2 = s2.Remove(lastSpace);
            }

            // Add Ellipsis if desired
            if (addEllipsis)
                s2 += "...";

            return s2;
        }

        /// <summary>
        /// Format Multiline to Br
        /// </summary>
        /// <param name="text">String contain multiline</param>
        /// <param name="noBr">Is br</param>
        /// <returns>Replace multiline to br</returns>
        public string FormatMultiline(string text, bool noBr = false)
        {
            if (text == null)
            {
                return "";
            }
            var result = text;
            if (result.Length <= 0)
            {
                return text;
            }
            result = result.Replace(Constants.vbCr + Constants.vbLf, Constants.vbLf);
            result = result.Replace(Constants.vbCr, Constants.vbLf);
            result = result.Replace(Constants.vbLf, noBr ? "" : "<br />");

            return result;
        }

        /// <summary>
        /// Format Br to Multiline
        /// </summary>
        /// <param name="text">String contain br html code</param>
        /// <returns>Replace br to multiline</returns>
        public string FormatBrToMultiline(string text)
        {
            if (text == null)
            {
                return "";
            }
            var result = text;
            if (result.Length <= 0)
            {
                return text;
            }
            result = result.Replace("<br />", Constants.vbLf);

            return result;
        }
        
        /// <summary>
        /// Return no html of string
        /// </summary>
        /// <param name="html">Html String</param>
        /// <returns>No Html</returns>
        public string NoHtml(string html)
        {
            return html == string.Empty ? string.Empty : Regex.Replace(html, "<[^>]*>", string.Empty);
        }

        /// <summary>
        /// Hàm trả về chuỗi datetime phù hợp với chuẩn RFC822
        /// </summary>
        /// <param name="dt">Ngày tháng nhập</param>
        /// <returns>Chuỗi RFC822</returns>
        public string GetRfc822Date(DateTime dt)
        {
            var offSet = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).Hours;
            var tz = "+" + Convert.ToString(offSet).PadLeft(2, Convert.ToChar("0"));
            if (offSet < 0)
            {
                var i = offSet * -1;
                tz = "-" + Convert.ToString(i).PadLeft(2, Convert.ToChar("0"));
            }
            return dt.ToString("ddd, dd MMM yyyy HH:mm:ss " + tz.PadRight(5, Convert.ToChar("0")));
        }

        /// <summary>
        /// Chuyển có dấu thành không dấu
        /// </summary>
        /// <param name="strEncode">Chuỗi có dấu</param>
        /// <returns>Chuỗi không dấu</returns>
        public string Utf8ToAscii(string strEncode)
        {
            strEncode = strEncode.ToLower();

            var p2 = Strings.Len(strEncode);
            var p1 = 0;
            var oStr = "";
            while (p1 < p2)
            {
                switch (strEncode.Substring(p1, 1))
                {
                    case "â":
                    case "ầ":
                    case "ấ":
                    case "ậ":
                    case "ẩ":
                    case "ẫ":
                    case "ă":
                    case "ắ":
                    case "ặ":
                    case "ằ":
                    case "ẵ":
                    case "ẳ":
                    case "à":
                    case "ạ":
                    case "ả":
                    case "á":
                    case "ã":
                        oStr += "a";
                        break;
                    case "Â":
                    case "Ầ":
                    case "Ấ":
                    case "Ậ":
                    case "Ẩ":
                    case "Ẫ":
                    case "Ă":
                    case "Ắ":
                    case "Ặ":
                    case "Ằ":
                    case "Ẵ":
                    case "Ẳ":
                    case "À":
                    case "Ạ":
                    case "Ả":
                    case "Á":
                    case "Ã":
                        oStr += "A";
                        break;
                    case "ế":
                    case "ề":
                    case "ễ":
                    case "ể":
                    case "ệ":
                    case "è":
                    case "ẹ":
                    case "ẻ":
                    case "ẽ":
                    case "ê":
                    case "é":
                        oStr += "e";
                        break;
                    case "Ế":
                    case "Ề":
                    case "Ễ":
                    case "Ể":
                    case "Ệ":
                    case "Ê":
                    case "É":
                    case "È":
                    case "Ẹ":
                    case "Ẻ":
                    case "Ẽ":
                        oStr += "E";
                        break;
                    case "ồ":
                    case "ô":
                    case "ộ":
                    case "ó":
                    case "ổ":
                    case "ỏ":
                    case "ơ":
                    case "ở":
                    case "ợ":
                    case "ỡ":
                    case "õ":
                    case "ờ":
                    case "ớ":
                    case "ọ":
                    case "ố":
                    case "ò":
                    case "ỗ":
                        oStr += "o";
                        break;
                    case "Ồ":
                    case "Ô":
                    case "Ộ":
                    case "Ó":
                    case "Ổ":
                    case "Ỏ":
                    case "Ơ":
                    case "Ở":
                    case "Ợ":
                    case "Ỡ":
                    case "Õ":
                    case "Ờ":
                    case "Ớ":
                    case "Ọ":
                    case "Ố":
                    case "Ò":
                    case "Ỗ":
                        oStr += "O";
                        break;
                    case "ù":
                    case "ú":
                    case "ụ":
                    case "ủ":
                    case "ư":
                    case "ừ":
                    case "ứ":
                    case "ử":
                    case "ự":
                    case "ữ":
                    case "ũ":
                        oStr += "u";
                        break;
                    case "Ù":
                    case "Ú":
                    case "Ụ":
                    case "Ủ":
                    case "Ư":
                    case "Ừ":
                    case "Ứ":
                    case "Ử":
                    case "Ự":
                    case "Ữ":
                    case "Ũ":
                        oStr += "U";
                        break;
                    case "ỷ":
                    case "ỵ":
                    case "ỹ":
                    case "ý":
                    case "ỳ":
                        oStr += "y";
                        break;
                    case "Ỷ":
                    case "Ỵ":
                    case "Ỹ":
                    case "Ý":
                    case "Ỳ":
                        oStr += "Y";
                        break;
                    case "í":
                    case "ì":
                    case "ỉ":
                    case "ĩ":
                    case "ị":
                        oStr += "i";
                        break;
                    case "Í":
                    case "Ì":
                    case "Ỉ":
                    case "Ĩ":
                    case "Ị":
                        oStr += "I";
                        break;
                    case "Đ":
                        oStr += "D";
                        break;
                    case "đ":
                        oStr += "d";
                        break;
                    case "[":
                    case "]":
                    case "#":
                    case ":":
                    case "/":
                    case "\\":
                    case "?":
                    case ">":
                    case "<":
                    case "*":
                    case "^":
                    case "~":
                    case "%":
                    case "+":
                    case "(":
                    case ")":
                    case ",":
                    case ";":
                    case "!":
                    case "@":
                    case "'":
                        oStr += "";
                        break;
                    case ".":
                    case " ":
                    case "&":
                    case "\"":
                    case "=":
                    case "$":
                    case "--":
                        oStr += "-";
                        break;
                    default:
                        oStr += strEncode.Substring(p1, 1);
                        break;
                }
                p1 = p1 + 1;
            }
            return oStr;
        }

        /// <summary>
        /// Hàm convert mã BBCode sang Html
        /// </summary>
        /// <param name="strTextToReplace">Chuỗi chứa mã BBCode</param>
        /// <returns>Chuỗi Html</returns>
        public string BbCode(string strTextToReplace)
        {
            //'Regex for URL tag without anchor 

            var regExp = new Regex("\\[url\\]([^\\]]+)\\[\\/url\\]");
            strTextToReplace = regExp.Replace(strTextToReplace, "<a href=\"$1\">$1</a>");
            //'Regex for URL with anchor 

            regExp = new Regex("\\[url=([^\\]]+)\\]([^\\]]+)\\[\\/url\\]");
            strTextToReplace = regExp.Replace(strTextToReplace, "<a href=\"$1\">$2</a>");
            //'Image regex

            regExp = new Regex("\\[img\\]([^\\]]+)\\[\\/img\\]");
            strTextToReplace = regExp.Replace(strTextToReplace, "<img src=\"$1\" />");
            //Bold text

            regExp = new Regex("\\[b\\](.+?)\\[\\/b\\]");
            strTextToReplace = regExp.Replace(strTextToReplace, "<b>$1</b>");
            //'Italic text 

            regExp = new Regex("\\[i\\](.+?)\\[\\/i\\]");
            strTextToReplace = regExp.Replace(strTextToReplace, "<i>$1</i>");
            //'Underline text 

            regExp = new Regex("\\[u\\](.+?)\\[\\/u\\]");
            strTextToReplace = regExp.Replace(strTextToReplace, "<u>$1</u>");
            //'Font size

            regExp = new Regex("\\[size=([^\\]]+)\\]([^\\]]+)\\[\\/size\\]");
            strTextToReplace = regExp.Replace(strTextToReplace, "<span style=\"font-size: $1px\">$2</span>");
            //'Font color

            regExp = new Regex("\\[color=([^\\]]+)\\]([^\\]]+)\\[\\/color\\]");
            strTextToReplace = regExp.Replace(strTextToReplace, "<span style=\"color: $1\">$2</span>");
            return strTextToReplace;
        }

        /// <summary>
        /// Hàm chuyển ngày tháng sang dạng số thực
        /// </summary>
        /// <returns>Chuỗi số thực</returns>
        public string DateTimeToNum()
        {
            return Strings.Replace(Strings.Replace(Strings.Replace(string.Format("{0:yyyy/MM/dd HH:mm:ss}", DateTime.Now), " ", ""), "/", ""), ":", "");
        }

        /// <summary>
        /// Right function string util
        /// </summary>
        /// <param name="strToCut">String content</param>
        /// <param name="length">Length of string to cut</param>
        /// <returns></returns>
        public string Right(string strToCut, int length)
        {
            return strToCut.Substring(strToCut.Length - length, length);
        }

        /// <summary>
        /// Left function string util
        /// </summary>
        /// <param name="strToCut">String content</param>
        /// <param name="length">Length of string to cut</param>
        /// <returns></returns>
        public string Left(string strToCut, int length)
        {
            return strToCut.Substring(0, length);
        }

        //Hàm check và sử dụng Microsoft Search trong SQL Server
        public string GetSearchStr(string iStr = "")
        {
            long p0 = 1;
            do
            {
                long p1 = Strings.InStr((int) p0, iStr, "&#", CompareMethod.Text);
                if (p1 == 0)
                    break; // TODO: might not be correct. Was : Exit Do
                long p2 = Strings.InStr((int) p1, iStr, ";", CompareMethod.Text);
                if (p2 == 0)
                {
                    p0 = p1 + 2;
                }
                else
                {
                    var stt = Strings.Mid(iStr, (int) (p1 + 2), (int) (p2 - p1 - 2));
                    if (Information.IsNumeric(stt))
                    {
                        iStr = Strings.Left(iStr, (int) (p1 - 1)) + Strings.ChrW((int) Convert.ToInt64(stt)) + Strings.Mid(iStr, (int) (p2 + 1));
                        p0 = p1 + 1;
                    }
                    else
                    {
                        p0 = p2 + 1;
                    }
                }
            } while (true);
            while (Strings.InStr(iStr, "  ") != 0)
            {
                iStr = Strings.Replace(iStr, "  ", " ");
            }

            iStr = Strings.Replace(iStr, "\" \"", "\" and \"");
            if (Strings.InStr(iStr, ",") > 0)
            {
                iStr = "\"" + Strings.Replace(iStr, ",", "\" or \"") + "\"";
            }
            return iStr;
        }

        /// <summary>
        /// Get file size
        /// </summary>
        /// <param name="size">Long size</param>
        /// <returns>String format</returns>
        public string GetFileSize(long size)
        {
            double dblSize = 0;
            string strUnit;
            if (size * 1.0 / 1024 > 1)
            {
                dblSize = size * 1.0 / 1024;
                strUnit = "KB";
                if (dblSize / 1024 > 1)
                {
                    dblSize = dblSize * 1.0 / 1024;
                    strUnit = "MB";
                }
            }
            else
            {
                strUnit = "byte";
            }
            return Strings.Format(dblSize, "#,###.##") + " " + strUnit;
        }

        /// <summary>
        /// Return safe string Json
        /// </summary>
        /// <param name="sIn">String JSON</param>
        /// <returns>Safe string json</returns>
        public string SafeJson(string sIn)
        {
            var sbOut = new StringBuilder(sIn.Length);
            foreach (var ch in sIn)
            {
                if (Char.IsControl(ch) || ch == '\'')
                {
                    var ich = Strings.AscW(ch);
                    sbOut.Append("\\u" + ich.ToString("x4"));
                    continue;
                }
                if (ch == '"' || ch == '\\' || ch == '/')
                {
                    sbOut.Append('\\');
                }
                sbOut.Append(ch);
            }
            return sbOut.ToString();
        }
    }
}